package jwanalytics.utils.date;

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

import junit.framework.TestCase;

/** JUnit test for BaseCalendar data methods. */
public class BaseCalendarTest extends TestCase {

	static Date sun3rdFeb2008 = new GregorianCalendar(2008,GregorianCalendar.FEBRUARY,3).getTime(); 		
	Date mon4thFeb2008 = new GregorianCalendar(2008,GregorianCalendar.FEBRUARY,4).getTime(); 
	Date tue5thFeb2008 = new GregorianCalendar(2008,GregorianCalendar.FEBRUARY,5).getTime(); 		
	Date wed6thFeb2008 = new GregorianCalendar(2008,GregorianCalendar.FEBRUARY,6).getTime(); 				
	Date thu7thFeb2008 = new GregorianCalendar(2008,GregorianCalendar.FEBRUARY,7).getTime(); 						
	Date fri8thFeb2008 = new GregorianCalendar(2008,GregorianCalendar.FEBRUARY,8).getTime(); 								
	Date sat9thFeb2008 = new GregorianCalendar(2008,GregorianCalendar.FEBRUARY,9).getTime(); 										
	Date sun10thFeb2008 = new GregorianCalendar(2008,GregorianCalendar.FEBRUARY,10).getTime(); 												
	Date mon11thFeb2008 = new GregorianCalendar(2008,GregorianCalendar.FEBRUARY,11).getTime(); 		
	Date mon18thFeb2008 = new GregorianCalendar(2008,GregorianCalendar.FEBRUARY,18).getTime();	
	
	/** . */
	public void testIsAParticularWeekday() {
		assertTrue(BaseCalendar.isAParticularWeekDay(fri8thFeb2008, Calendar.FRIDAY));
	}
			
	/** Tests making a date the first second of the day it belongs to. */
	public void testMakeItFirstSecondOfDay() {
		GregorianCalendar c = new GregorianCalendar(2005, Calendar.MAY, 15, 23, 06, 07);
		Date date = c.getTime();
		Date date1stSec = BaseCalendar.makeItFirstSecondOfDay(date);
		Date dateClone = (Date) date.clone();
		Date dateClone1stSec = BaseCalendar.makeItFirstSecondOfDay(dateClone);
		assertTrue(date1stSec.equals(dateClone1stSec));
	}

	/** Tests the function of advancing dates or retroceding days on the calendar. */
	public void test10DaysFromDate() {
		GregorianCalendar c = new GregorianCalendar(2005, Calendar.MAY, 2, 4, 10, 59);
		GregorianCalendar c2 = new GregorianCalendar(2005, Calendar.MAY, 12, 4, 10, 59);		
		assertTrue(c2.getTime().equals(BaseCalendar.addDays(c.getTime(),10)));
	}

		
	/** Tests the function of advancing dates or retroceding days on the calendar. */
	public void test1DayFromDate() {
		GregorianCalendar c = new GregorianCalendar(2005, Calendar.MAY, 15, 23, 06, 07);
		GregorianCalendar c2 = new GregorianCalendar(2005, Calendar.MAY, 16, 23, 06, 07);
		assertTrue(c2.getTime().equals(BaseCalendar.addDays(c.getTime(),1)));
	}
		
	/** Test finding the next monday. */
	public void testNextMonday() throws Exception { 				
		Date[] dates = {mon4thFeb2008, tue5thFeb2008, wed6thFeb2008, thu7thFeb2008, fri8thFeb2008, sat9thFeb2008, sun10thFeb2008};
		assertTrue(BaseCalendar.areAtTheSameDay(BaseCalendar.nextWeekdayOfType(sun3rdFeb2008, Calendar.MONDAY), mon4thFeb2008));
		for (int i = 0; i < dates.length; ++i) {
			Date nextMonday = BaseCalendar.nextWeekdayOfType(dates[i], Calendar.MONDAY);
			this.assertTrue(BaseCalendar.areAtTheSameDay(nextMonday, mon11thFeb2008));
		}
		assertTrue(BaseCalendar.areAtTheSameDay(BaseCalendar.nextWeekdayOfType(mon11thFeb2008, Calendar.MONDAY), mon18thFeb2008));
		assertTrue(BaseCalendar.areAtTheSameDay(BaseCalendar.nextWeekdayOfType(sun3rdFeb2008, Calendar.TUESDAY), tue5thFeb2008));		
		assertFalse(BaseCalendar.areAtTheSameDay(BaseCalendar.nextWeekdayOfType(sun3rdFeb2008, Calendar.TUESDAY), mon18thFeb2008));
		assertTrue(BaseCalendar.areAtTheSameDay(BaseCalendar.nextWeekdayOfType(sun3rdFeb2008, Calendar.SUNDAY), sun10thFeb2008));		
	}
		
	/** Tests if a date is a weekend. */
	public void testIsWeekend() {
		GregorianCalendar c = new GregorianCalendar(2005, Calendar.MAY, 1, 4, 10, 59);
		this.assertTrue(BaseCalendar.isWeekend(c.getTime()));		
	}
		
	/** Tests if a date is a weekend. */
	public void testIsWeekDay() {
		GregorianCalendar c = new GregorianCalendar(2005, Calendar.MAY, 2, 4, 10, 59);
		this.assertTrue(BaseCalendar.isWeekDay(c.getTime()));		
	}
		
	/** Tests difference in days calculation. */
	public void testDifferenceInDays() {
		GregorianCalendar c = new GregorianCalendar(2005, Calendar.MAY, 2, 4, 10, 59); 
		GregorianCalendar cal = new GregorianCalendar(2005, Calendar.AUGUST, 2, 4, 10, 59);
		assertTrue(89 < BaseCalendar.approximateDifferenceInDays(c.getTime(), cal.getTime()));		
		assertTrue(94 > BaseCalendar.approximateDifferenceInDays(c.getTime(), cal.getTime()));				
	}
		
	public void testDifferenceInDays2() {
		GregorianCalendar cA = new GregorianCalendar(2005, Calendar.MAY, 30, 4, 10, 59); //30 31 
		GregorianCalendar calA = new GregorianCalendar(2005, Calendar.JUNE, 4, 4, 10, 59); //1 2 3 4
		assertTrue(5 == BaseCalendar.approximateDifferenceInDays(cA.getTime(), calA.getTime()));
	}

	public void testDifferenceInDays3() {
		GregorianCalendar cA = new GregorianCalendar(2005, Calendar.MAY, 29, 14, 00, 00);
		GregorianCalendar calA = new GregorianCalendar(2005, Calendar.MAY, 30, 10, 00, 00);
		assertTrue(0 == BaseCalendar.approximateDifferenceInDays(cA.getTime(), calA.getTime()));
	}
	
	
	public void testDaysSpan() {
		GregorianCalendar cA = new GregorianCalendar(2005, Calendar.MAY, 28, 4, 10, 59); 
		GregorianCalendar calA = new GregorianCalendar(2005, Calendar.MAY, 28, 6, 10, 59); 
		assertEquals(1, BaseCalendar.daysSpan(cA.getTime(), calA.getTime()));
		GregorianCalendar cB = new GregorianCalendar(2005, Calendar.MAY, 28, 4, 10, 59); 
		GregorianCalendar calB = new GregorianCalendar(2005, Calendar.MAY, 29, 6, 10, 59);
		assertEquals(1, BaseCalendar.approximateDifferenceInDays(cB.getTime(), calB.getTime()));
		assertEquals(2, BaseCalendar.daysSpan(cB.getTime(), calB.getTime()));
		GregorianCalendar cC = new GregorianCalendar(2005, Calendar.MAY, 28, 4, 10, 59); 
		GregorianCalendar calC = new GregorianCalendar(2005, Calendar.MAY, 29, 3, 10, 59);
		assertEquals(0, BaseCalendar.approximateDifferenceInDays(cC.getTime(), calC.getTime()));
		assertEquals(2, BaseCalendar.daysSpan(cC.getTime(), calC.getTime()));		
		GregorianCalendar cD = new GregorianCalendar(2005, Calendar.MAY, 28, 4, 10, 59); 
		GregorianCalendar calD = new GregorianCalendar(2005, Calendar.MAY, 30, 3, 10, 59);
		assertEquals(1, BaseCalendar.approximateDifferenceInDays(cD.getTime(), calD.getTime()));
		assertEquals(3, BaseCalendar.daysSpan(cD.getTime(), calD.getTime()));		
	}
		
	/** Tests the function of advancing dates or retroceding days on the calendar. */
	public void testSetHour() {
		GregorianCalendar c = new GregorianCalendar(2005, Calendar.MAY, 15, 23, 6, 7);
		GregorianCalendar c2 = new GregorianCalendar(2005, Calendar.MAY, 16, 3, 8, 1);
		//
		GregorianCalendar result = new GregorianCalendar(2005, Calendar.MAY, 15, 3, 8, 01);
		Date hourSet = BaseCalendar.setHour(c.getTime(), c2.getTime());
		assertTrue(result.getTime().equals(hourSet));
	}	
		
}

